<?php
Zend::loadClass('Lead_EDO_Datatype_Relation');

class Lead_EDO_Datatype_Relation_HasOne extends Lead_EDO_Datatype_Relation
{
   	
   	private $_className;
   	
   	private $_obj;
   	private $_nuObj;
   	
   	private $_value;
   	
    public function __construct(Lead_EDO_Object_Abstract $owner, $config = array())
	{
		parent::__construct($owner, $config);	

		$this->_className = $config['class_name'];
		        $this->_foreignKey = (isset($config['foreign_key'])) ? $config['foreign_key'] : $this->getOwner()->getClass() . '_id';
		$this->getOwner()->attach($this, 'afterFetch', '_afterFetchActions');
		$this->getOwner()->attach($this, 'onSaveSuccess', '_save');
	}
	
	
	public function _afterFetchActions()
	{
	    $this->_obj = null;
	}
	
	
	public function _save()
	{
	    if($this->_obj)
	    {
	       $this->_obj->save();
	    }

  	    if($this->_nuObj)
	    {
	       $this->_nuObj->save();
	    }
	}
	

	
	
	
	public function getValue()
	{
	 	    
	    if(!$this->_obj)
	    {
      	    $obj = $this->getOwner()->edo->get($this->_className);
	        $args = $this->parseConditionsToValues();
	        
	        $args[] = array($this->getForeignKey(), '=', $this->getOwner()->id); 	    

	        
	                
	        $this->_obj = $obj->getFinder()->findFirst($args);
    	    
	        
	        
	    
	    }
	    return $this->_obj;
	}
	
	
	
   	public function getOptions()
    {
   	    if(!isset(EDO::$relationOptions[$this->getOwner()->getClass()][$this->getName()]))
	    {
	       $args = $this->parseConditionsToValues();
           	       	       
	       $obj = $this->getOwner()->getHandler()->get($this->getClassName());
	       
           if($this->getConfig('order'))
           {
               $obj->getFinder()->addOrderer($this->getConfig('order'));
           }
           
           
           $query = $obj->getFinder()->getQuery();
                                 
           $display = $this->getConfig('display');
           $regexp = "/(\%([a-zA-Z_]*))/si";
           preg_match_all($regexp, $display, $fields);
           $fields = $fields[2];
           $fields = array_unique($fields);
           foreach($fields as $field)
           {
               $table = $obj->getFieldsTable($field);
               
               $query->addField("{$table}.{$field}", false);
                                             
               if(!$query->tableIsJoined($table))
                    $query->addJoin($table, 'INNER', "edo.id = {$table}.id");
           }
          
           $result = $query->ldb->getAll($query->getSQL());
           
           
           
           $opzions = array();
           foreach($result as $row)
           {
               $display2 = $display;
               foreach($fields as $field)
               {
                    $display2 = str_ireplace("%{$field}", $row[$field], $display2);
               }
               $opzions[$row['id']] = $display2;
           }

           
           /*
           
           $options = $obj->getFinder()->findAll($args, false, 'fast2');
	       $this->_options = array();
           foreach($options as $obj)
	       {
	          $this->_options[$obj->id] = $this->resolveTags($obj, $this->getConfig('display'));
	       }
           */
           
           EDO::$relationOptions[$this->getOwner()->getClass()][$this->getName()];
	    }
	    
	    return EDO::$relationOptions[$this->getOwner()->getClass()][$this->getName()];

   
	    
	}


	public function validate($value)
	{
	    if(empty($value))
	       return null;
	       
	    if(is_numeric($value))
	       return $value;
	       
	    return false;
	}
	
	

	
	public function setValue($value, $validate = true)
	{
	    
  	    if($validate)
            $value = $this->validate($value);
        
                       
        if($value !== false)    
        {
	       $this->_obj = $this->getValue();
	       if($this->_obj)
	       {
	           if($this->_obj->id != $value)
	           {
	               $this->_obj->setField($this->getForeignKey(), null);
	               
	               $this->_nuObj = $this->_obj->get();
	               $this->_nuObj->fetch($value);
	               $this->_nuObj->setField($this->getForeignKey(), $this->getOwner()->id);
	           }
	               
	       }
	       else 
	       {
	           $this->_obj = $this->getOwner()->edo->get($this->getClassName());
	           $this->_obj->fetch($value);
	           $this->_obj->setField($this->getForeignKey(), $this->getOwner()->id);
	       }
	       
	       
	        
	     
	    }
	    
	    	
        return ($value === false) ? false : true;	    
	}
	
	
	
	public function joinTo(Query $query)
	{
	    
	    $obj = $this->getOwner()->edo->get($this->_className);
        $tables = $obj->getTables();
	    	    
        $args = $this->parseConditionsToTables();
        if($args)
        {
            $wg = $query->addWhereGroup();
            foreach($args as $argArr)
            {
               $argTbl = $obj->getFieldsTable($argArr[0]);
               $argArr[0] = $argTbl . '.' . $argArr[0];
               	        
                call_user_func_array(array($wg, 'addWhereCond'), $argArr);    
            }
        }
	    	    
	    	    	    
	    
        
        $fKeyTable = $obj->getFieldObject($this->getForeignKey())->getTable();
        
 
        
        $firstTable = array_shift($tables);
        $query->addJoin($firstTable, 'INNER', "{$fKeyTable}.{$this->getForeignKey()} = {$this->getOwner()->getFirstTable()}.id");
        
        foreach($tables as $table)
        {
            $query->addJoin($table, 'INNER', "{$firstTable}.id = {$table}.id");
        }
       

	}
	
    public function getOpposite()
    {
        $obj = $this->getOwner()->edo->get($this->getClassName());
         	     	   
  	   foreach($obj->getRelationObjects() as $relObj) 
       {
           if($relObj->getForeignKey() == $this->getForeignKey())
            return $obj->getClass() . '_' . $relObj->getName();
       }
    }
}